package com.example.wanandroidsdk.http;

import android.util.MalformedJsonException;

import com.example.wanandroidsdk.constants.Constants;
import com.example.wanandroidsdk.utils.LogUtils;
import com.example.wanandroidsdk.utils.NetworkUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;

import static com.example.wanandroidsdk.constants.Constants.DEFAULT_TIMEOUT;
import static com.example.wanandroidsdk.constants.Constants.TAG;

public class WanHttpUtils {
    private static String msg = "";

    public static class RequestThread extends Thread {
        private final Map<String, String> params;
        private final WanOnResponseListener listener;
        private final byte[] lock = new byte[0];
        private boolean isCancel = false;

        public RequestThread(Map<String, String> params, WanOnResponseListener listener) {
            this.params = params;
            this.listener = listener;
        }

        public void run() {
            WanAndroidHttpResult<String> result = Objects.equals(params.get("Method"), "POST") ? WanHttpUtils.doRequest(this.params) : WanHttpUtils.doRequestGet(this.params);
            synchronized (this.lock) {
                if (!this.isCancel) {
                    this.listener.onResponse(result);
                }
            }
        }
    }

    public static WanAndroidHttpResult<String> doRequest(Map<String, String> params) {
        if (params == null) {
            return null;
        } else {
            WanAndroidHttpResult<String> result = new WanAndroidHttpResult<>();
            try {
                URL url = new URL(params.get("url"));
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod(params.get("Method"));
                connection.setReadTimeout(DEFAULT_TIMEOUT);
                connection.setConnectTimeout(DEFAULT_TIMEOUT);
                connection.setDoOutput(true);
                connection.setDoInput(true);
                connection.setRequestProperty("Connection", "Keep-Alive");
                connection.setRequestProperty("Charset", "UTF-8");
                connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
                connection.setRequestProperty("accept", "application/json");
                String requestParamJsonObject = params.get("body");
                if (requestParamJsonObject != null && !"".equals(requestParamJsonObject.trim())) {
                    byte[] bytes = requestParamJsonObject.getBytes();
                    connection.setRequestProperty("Content-Length", String.valueOf(bytes.length));
                    OutputStream outputStream = connection.getOutputStream();
                    outputStream.write(bytes);
                    outputStream.flush();
                    outputStream.close();
                }

                int responseCode = connection.getResponseCode();
                if (200 == responseCode) {
                    result.isBizSucceed(true);
                    result.setData(getResponseDataString(connection.getInputStream()));

                } else {
                    result.isBizSucceed(false);
                    result.setErrorMsg("errorCode:" + responseCode + connection.getResponseMessage());
                }
            } catch (Exception e) {
                showErrorMsg(result,e);
            }
            return result;
        }
    }

    public static WanAndroidHttpResult<String> doRequestGet(Map<String, String> params) {
        if (params == null) {
            return null;
        } else {
            WanAndroidHttpResult<String> result = new WanAndroidHttpResult<>();
            try {
                URL url = new URL(params.get("url"));
                LogUtils.d(TAG, url.toString());
                LogUtils.d(TAG,params.toString() + " --params-- ");
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setReadTimeout(DEFAULT_TIMEOUT);
                connection.setConnectTimeout(DEFAULT_TIMEOUT);
                int responseCode = connection.getResponseCode();
                if (200 == responseCode) {
                    result.isBizSucceed(true);
                    result.setData(getResponseDataString(connection.getInputStream()));
                } else {
                    result.isBizSucceed(false);
                    result.setErrorMsg("errorCode:" + responseCode + connection.getResponseMessage());
                }
            } catch (Exception e) {
                showErrorMsg(result,e);
            }
            return result;
        }
    }

    private static String getResponseDataString(InputStream inputStream) {
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        StringBuilder stringBuilder = new StringBuilder();
        String temp;
        try {
            while ((temp = bufferedReader.readLine()) != null) {
                stringBuilder.append(temp);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStreamReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return stringBuilder.toString();
    }

    private static void showErrorMsg(WanAndroidHttpResult<String> result, Exception e) {
        if (!NetworkUtils.isConnected()) {
            msg = Constants.NETWORK_ERROR;
        } else if (e instanceof SocketTimeoutException) {
            msg = Constants.NETWORK_TIMEOUT;
        } else if (e instanceof MalformedJsonException) {
            msg = Constants.DATA_JSON_ERROR;
        } else {
            msg = Constants.REQUEST_ERROR + e.getMessage();
        }
        result.setErrorMsg(msg);
    }
}
